package main

import (
	"bufio"
	bytes2 "bytes"
	"encoding/binary"
	"fmt"
	"github.com/astaxie/beego/logs"
	"github.com/imroc/biu"
	"net"
	"strings"
	"time"
)

func main() {
	//10.14.1.88:59336
	//主动连接服务器
	for {
		time.Sleep(1 * time.Second)
		hawkServer, err := net.ResolveTCPAddr("tcp", ":7778")
		conn, err := net.DialTCP("tcp", nil, hawkServer)
		if err != nil {
			continue
		}
		bools := make(chan bool, 1)
		go func() {
			_, err := conn.Write(anchorInfo3())
			if err != nil {
				logs.Error(err.Error())
				conn.Close()
				bools <- true
			}
			_, err = conn.Write(heart3())
			if err != nil {
				logs.Error(err.Error())
				conn.Close()
				bools <- true
			}
			reader := bufio.NewReader(conn)
			for {
				//接收服务数据
				buf := make([]byte, 2048) //1024大小的缓冲区
				n, err := reader.Read(buf)
				if err != nil {
					logs.Error(err.Error())
					conn.Close()
					bools <- true
					break
				}
				if len(buf) == 0 {
					continue
				}
				decode3(conn, buf[0:n])
			}
		}()
		<-bools
	}
}

func heart3() []byte {
	bytes := make([]byte, 22)
	bytes[0] = 0x2
	binary.LittleEndian.PutUint16(bytes[1:3], uint16(16))
	bytes[3] = 0x21
	strings.NewReader("AnchorHeartbeat").Read(bytes[4:19])
	binary.LittleEndian.PutUint16(bytes[len(bytes)-3:len(bytes)-1], 0x3)
	bytes[len(bytes)-1] = 0x3
	return bytes
}

func anchorInfo3() []byte {
	a := "aaaaaaaabbbbbbbb"
	v := "v1.3.0"
	bytes := make([]byte, 70)
	bytes[0] = 0x2
	binary.LittleEndian.PutUint16(bytes[1:3], uint16(64))
	bytes[3] = 0x42
	var as []byte
	fmt.Fscanf(strings.NewReader(a), "%x", &as)
	bytes2.NewBuffer(reversal3(as)).Read(bytes[4:12])
	strings.NewReader(v).Read(bytes[12:66])
	binary.LittleEndian.PutUint16(bytes[66:68], uint16(123))
	bytes[len(bytes)-1] = 0x3
	return bytes
}

//解码
func decode3(conn *net.TCPConn, data []byte) {
	fnCE := data[0]
	switch fnCE {
	case 0x21:
		//心跳
		conn.Write(heart3())
	case 0x30:
		//CCPTX_Report
		logs.Debug("0x30")
	case 0x31:
		//CCPRX_Report
		logs.Debug("0x31")
	case 0x32:
		//BLINK_Report
		logs.Debug("0x32")
	case 0x42:
		//基站信息
		logs.Debug("0x42")
	case 0x43:
		logs.Debug("ox43")
		sr := biu.ByteToBinaryString(data[1])
		primarySyncRef := fmt.Sprintf("%x", data[2:10])
		lag := binary.BigEndian.Uint32(data[10:14])
		logs.Debug(sr, primarySyncRef, lag)
	case 0x44:
		//配置基站射频参数
		logs.Debug("0x44")
		low4 := getLow43(data[1])
		height4 := getHeight43(data[1])
		DataRate := fmt.Sprintf("%d", data[2])
		Preamble := fmt.Sprintf("%d", data[3])
		psr := fmt.Sprintf("%d", data[4])
		pac := getLow43(data[5])
		nsfd := getHeight43(data[5])
		logs.Debug(low4, height4, DataRate, Preamble, psr, pac, nsfd)
	case 0x53:
		//BLINK_Report
		logs.Debug("0x53")
	case 0x57:
		logs.Debug("0x57")
	default:
		//logs.Error("fnCE is not match,current[%s]", fmt.Sprintf("%x", data[0]))
		return
	}
}

func getHeight43(data byte) byte { //获取高四位
	return (data & 0xf0) >> 4
}

//字节高低位组装
func ByteCombinations3(high, low int) byte {
	return getLow43(byte(high))<<4 | getLow43(byte(low))
}

func getLow43(data byte) byte { //获取低四位
	return data & 0x0f
}

//字节高低位逆转
func reversal3(data []byte) []byte {
	for i, j := 0, len(data)-1; i < j; i, j = i+1, j-1 {
		data[i], data[j] = data[j], data[i]
	}
	return data
}
